﻿//
// Copyright (c) 2010
// by Ashish Agrawal and Chris Paterra
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//

using System.Collections.Generic;
using SimpleBlog.Components.Data;
using DotNetNuke.Common.Utilities;
using SimpleBlog.Components.Entities;

namespace SimpleBlog.Components.Controllers
{
	public class SimpleBlogController : ISimpleBlogController {

		private readonly IDataProvider _dataProvider;

		#region Constructors

		/// <summary>
		/// 
		/// </summary>
		public SimpleBlogController()
		{
			_dataProvider = DotNetNuke.ComponentModel.ComponentFactory.GetComponent<IDataProvider>();
			if (_dataProvider != null) return;

			// get the provider configuration based on the type
			var defaultprovider = DotNetNuke.Data.DataProvider.Instance().DefaultProviderName;
			const string dataProviderNamespace = "SimpleBlog.Components.Data";

			if (defaultprovider == "SqlDataProvider") 
			{
				_dataProvider = new SqlDataProvider();
			}
			else 
			{
				var providerType = dataProviderNamespace + "." + defaultprovider;
				_dataProvider = (IDataProvider)DotNetNuke.Framework.Reflection.CreateObject(providerType, providerType, true);
			}

			DotNetNuke.ComponentModel.ComponentFactory.RegisterComponentInstance<IDataProvider>(_dataProvider);
		}
		  
		/// <summary>
		/// 
		/// </summary>
		/// <param name="dataProvider"></param>
		public SimpleBlogController(IDataProvider dataProvider)
		{
			//DotNetNuke.Common.Requires.NotNull("dataProvider", dataProvider);
			_dataProvider = dataProvider;
		}

		#endregion

		#region Public Methods

		#region Entry

		/// <summary>
		/// Returns a collection of all blog entries for management (ie. multiple rows of data).
		/// </summary>
		/// <param name="moduleId"></param>
		/// <param name="pageSize"></param>
		/// <param name="pageIndex"></param>
		/// <returns>This is meant for use by users with edit permission on the module instance.</returns>
		List<EntryInfo> ISimpleBlogController.GetAllEntries(int moduleId, bool publish, int pageSize, int pageIndex) 
		{
			//DotNetNuke.Common.Requires.PropertyNotNegative("moduleId", "", moduleId);
			//DotNetNuke.Common.Requires.PropertyNotNegative("pageSize", "", pageSize);
			//DotNetNuke.Common.Requires.PropertyNotNegative("pageIndex", "", pageIndex);

			return CBO.FillCollection<EntryInfo>(_dataProvider.GetAllEntries(moduleId, publish, pageSize, pageIndex));
		}

		/// <summary>
		/// Returns a collection of published blog entries (ie. multiple rows of data). 
		/// </summary>
		/// <param name="moduleId"></param>
		/// <param name="pageSize"></param>
		/// <param name="pageIndex"></param>
		/// <returns></returns>
		public List<EntryInfo> GetPublishedModuleEntries(int moduleId, int pageSize, int pageIndex) {
			//string strCacheKey = "SimpleBlog-Cache" + "-" + moduleId;
			//colEntries = (List<EntryInfo>)DataCache.GetCache(strCacheKey);

			//if (colEntries == null) {
			//     // caching settings
			//     Int32 timeOut = 20 * Convert.ToInt32(Host.PerformanceSetting);

			var colEntries = CBO.FillCollection<EntryInfo>(_dataProvider.GetPublishedModuleEntries(moduleId, pageSize, pageIndex));

			////Cache Entries if timeout > 0 and Entry collection is not null
			//if (timeOut > 0 & colEntries != null) {
			//     DataCache.SetCache(strCacheKey, colEntries, TimeSpan.FromMinutes(timeOut));
			//}
			//}
			return colEntries;
		}

		public List<EntryInfo> GetPublishedPortalEntries(int portalID) {
			var colEntries = CBO.FillCollection<EntryInfo>(_dataProvider.GetPublishedPortalEntries(portalID));
			return colEntries;
		}


		/// <summary>
		/// returns a single Blog Entry (equivalent to a single row of data)
		/// </summary>
		/// <param name="entryId"></param>
		/// <returns></returns>
		EntryInfo ISimpleBlogController.GetEntry(int entryId, int moduleId) {
			return (EntryInfo)CBO.FillObject(_dataProvider.GetEntry(entryId, moduleId), typeof(EntryInfo));
		}

		/// <summary>
		/// Adds an entry to the data store and returns the EntryInfo object (updated with EntryId and ContentItemId) that we just added to the data store.
		/// </summary>
		/// <param name="objEntry"></param>
		/// <returns>The EntryInfo object we added to the data store, along w/ it's newly created ContentItemId populated.</returns>
		EntryInfo ISimpleBlogController.AddEntry(EntryInfo objEntry, int tabId) 
		{
			objEntry.EntryId =  _dataProvider.AddEntry(objEntry.Title, objEntry.Summary, objEntry.BlogContent, objEntry.AllowComments, objEntry.Publish, objEntry.PublishedByUserId, objEntry.PublishOnDate, objEntry.ModuleId, objEntry.PortalId, objEntry.CreatedByUserId, objEntry.CreatedOnDate);

			objEntry.ContentItemId = CompleteEntryCreation(objEntry, tabId);
			
			return objEntry;
		}

		/// <summary>
		/// Updates an existing entry  in the data store.
		/// </summary>
		/// <param name="objEntry"></param>
		void ISimpleBlogController.UpdateEntry(EntryInfo objEntry, int tabId) {
			_dataProvider.UpdateEntry(objEntry.EntryId, objEntry.Title, objEntry.Summary, objEntry.BlogContent, objEntry.AllowComments, objEntry.Publish, objEntry.PublishedByUserId, objEntry.PublishOnDate, objEntry.ModuleId, objEntry.ContentItemId, objEntry.LastModifiedByUserId, objEntry.LastModifiedOnDate);

			CompleteEntryUpdate(objEntry, tabId);
		}

		/// <summary>
		/// Deletes an entry from the data store.
		/// </summary>
		/// <param name="entryId"></param>
		/// <param name="moduleId"></param>
		void ISimpleBlogController.DeleteEntry(int entryId, int moduleId) {
			_dataProvider.DeleteEntry(entryId, moduleId);
		}

		#endregion

		/// <summary>
		/// This completes the things necessary for creating a content item in the data store. 
		/// </summary>
		/// <param name="objEntry">The EntryInfo entity we just created in the data store.</param>
		/// <param name="tabId">The page we will associate with our content item.</param>
		/// <returns>The ContentItemId primary key created in the Core ContentItems table.</returns>
		private static int CompleteEntryCreation(EntryInfo objEntry, int tabId) {
			var cntTaxonomy = new Taxonomy.Content();
			var objContentItem = cntTaxonomy.CreateContentItem(objEntry, tabId);

			return objContentItem.ContentItemId;
		}

		private static void CompleteEntryUpdate(EntryInfo objEntry, int tabId) {
			var cntTaxonomy = new Taxonomy.Content();
			cntTaxonomy.UpdateContentItem(objEntry, tabId);

			// clear active entry cache and single item cache.
		}

		#endregion

	}
}